#include <AVUIAffineTransform3D.h>

namespace AVUI {

class TranslateTransform3D : public AffineTransform3D
{
public:
    TranslateTransform3D() : m_cachedOffsetXValue(0.0f), m_cachedOffsetYValue(0.0f), m_cachedOffsetZValue(0.0f) { };
    TranslateTransform3D(const Vector3D& offset);
    TranslateTransform3D(float offsetX, float offsetY, float offsetZ);
    ~TranslateTransform3D() { }

    DECLARE_ELEMENT(TranslateTransform3D, AffineTransform3D);

    DECLARE_DEPENDENCY_PROPERTY(OffsetX);
    float get_OffsetX() { return m_cachedOffsetXValue; }
    void set_OffsetX(float value) { SetValue(get_OffsetXProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(OffsetY);
    float get_OffsetY() { return m_cachedOffsetYValue; }
    void set_OffsetY(float value) { SetValue(get_OffsetYProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(OffsetZ);
    float get_OffsetZ() { return m_cachedOffsetZValue; }
    void set_OffsetZ(float value) { SetValue(get_OffsetZProperty(), AVUI::BoxValue(value)); } 

    virtual Matrix3D get_Value();

    virtual void Append(Matrix3D* pMatrix) AVUI_OVERRIDE
    {
        *pMatrix = *pMatrix * get_Value();
    }

protected:
    virtual TRefCountedPtr<Freezable> CreateInstanceCore() AVUI_OVERRIDE { return object_allocate<TranslateTransform3D>().get_Ptr(); }

private:

    static void OffsetXPropertyChanged(DependencyObject* pDO, DependencyPropertyChangedEventArgs* e);
    static void OffsetYPropertyChanged(DependencyObject* pDO, DependencyPropertyChangedEventArgs* e);
    static void OffsetZPropertyChanged(DependencyObject* pDO, DependencyPropertyChangedEventArgs* e);

    float m_cachedOffsetXValue;
    float m_cachedOffsetYValue;
    float m_cachedOffsetZValue;

    static void StaticConstructor();

};


typedef TRefCountedPtr<TranslateTransform3D> TranslateTransform3DPtr;


}; // namespace AVUI
